Date: Thu Feb 27 13:12:41 2020
Scientist: Ran Yin
Sequencing (Waksman): Dibyendu Kumar
Statistics: Davit Sargsyan
Principal Investigator: Ah-Ng Kong

# Taxonomic Ranks:
# **K**ing **P**hillip **C**an n**O**t **F**ind **G**reen **S**ocks
# * Kingdom                
# * Phylum                    
# * Class                   
# * Order                   
# * Family     
# * Genus     
# * Species  
```r
# options(stringsAsFactors = FALSE,
#         scipen = 999)
# # Increase mmemory size to 64 Gb----
# invisible(utils::memory.limit(65536))
# str(knitr::opts_chunk$get())
# # NOTE: the below does not work!
# knitr::opts_chunk$set(echo = FALSE, 
#                       message = FALSE,
#                       warning = FALSE,
#                       error = FALSE)
# require(knitr)
# require(kableExtra)
require(phyloseq)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBwaHlsb3NlcVxuIn0= -->

Loading required package: phyloseq




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuIyByZXF1aXJlKHNoaW55KVxucmVxdWlyZShkYXRhLnRhYmxlKVxuYGBgXG5gYGAifQ== -->

```r
```r
# require(shiny)
require(data.table)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBkYXRhLnRhYmxlXG5kYXRhLnRhYmxlIDEuMTIuMiB1c2luZyAxOCB0aHJlYWRzIChzZWUgP2dldERUdGhyZWFkcykuICBMYXRlc3QgbmV3czogci1kYXRhdGFibGUuY29tXG4ifQ== -->

Loading required package: data.table data.table 1.12.2 using 18 threads (see ?getDTthreads). Latest news: r-datatable.com




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShnZ3Bsb3QyKVxuYGBgXG5gYGAifQ== -->

```r
```r
require(ggplot2)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBnZ3Bsb3QyXG4ifQ== -->

Loading required package: ggplot2




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShwbG90bHkpXG5gYGBcbmBgYCJ9 -->

```r
```r
require(plotly)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBwbG90bHlcblxuQXR0YWNoaW5nIHBhY2thZ2U6IMOi4oKsy5xwbG90bHnDouKCrOKEolxuXG5UaGUgZm9sbG93aW5nIG9iamVjdCBpcyBtYXNrZWQgZnJvbSDDouKCrMuccGFja2FnZTpnZ3Bsb3Qyw6LigqzihKI6XG5cbiAgICBsYXN0X3Bsb3RcblxuVGhlIGZvbGxvd2luZyBvYmplY3QgaXMgbWFza2VkIGZyb20gw6LigqzLnHBhY2thZ2U6c3RhdHPDouKCrOKEojpcblxuICAgIGZpbHRlclxuXG5UaGUgZm9sbG93aW5nIG9iamVjdCBpcyBtYXNrZWQgZnJvbSDDouKCrMuccGFja2FnZTpncmFwaGljc8Oi4oKs4oSiOlxuXG4gICAgbGF5b3V0XG4ifQ== -->

Loading required package: plotly

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

last_plot

The following object is masked from ‘package:stats’:

filter

The following object is masked from ‘package:graphics’:

layout



<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShEVClcbmBgYFxuYGBgIn0= -->

```r
```r
require(DT)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBEVFxuIn0= -->

Loading required package: DT




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShsbWVyVGVzdClcbmBgYFxuYGBgIn0= -->

```r
```r
require(lmerTest)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBsbWVyVGVzdFxuTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBsbWU0XG5Mb2FkaW5nIHJlcXVpcmVkIHBhY2thZ2U6IE1hdHJpeFxuXG5BdHRhY2hpbmcgcGFja2FnZTogw6LigqzLnGxtZXJUZXN0w6LigqzihKJcblxuVGhlIGZvbGxvd2luZyBvYmplY3QgaXMgbWFza2VkIGZyb20gw6LigqzLnHBhY2thZ2U6bG1lNMOi4oKs4oSiOlxuXG4gICAgbG1lclxuXG5UaGUgZm9sbG93aW5nIG9iamVjdCBpcyBtYXNrZWQgZnJvbSDDouKCrMuccGFja2FnZTpzdGF0c8Oi4oKs4oSiOlxuXG4gICAgc3RlcFxuIn0= -->

Loading required package: lmerTest Loading required package: lme4 Loading required package: Matrix

Attaching package: ‘lmerTest’

The following object is masked from ‘package:lme4’:

lmer

The following object is masked from ‘package:stats’:

step



<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuc291cmNlKFxcc291cmNlL2Z1bmN0aW9uc19tYXkyMDE5LlJcXClcbiMgT24gV2luZG93cyBzZXQgbXVsdGl0aHJlYWQ9RkFMU0UtLS0tXG5tdCA8LSBUUlVFXG5gYGBcbmBgYCJ9 -->

```r
```r
source(\source/functions_may2019.R\)
# On Windows set multithread=FALSE----
mt <- TRUE

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->


# Introduction
C57BL/6 wild-type (WT) and Nrf-2 double-knock-out (KO -/-) mice were given 2-week microbiome stabilization process using AIN93M diet and 8 more weeks to treat with either AIN93M or AIN93M 5% PEITC diet. Fecal samples were collected weekly, immediately frozen in liquid nitrogen and stored at -80^o^C. Serum, cecal, colon epithelial and whole colon tissues at week 10 were also collected for further analyses. Baseline, week 1 and 4 fecal samples were selected for 16s rRNA sequencing.  
  
This document examines results from the WT mice samples.  
  
We will attampt to answer the following questions:  
1. Did microbiome change over time?  
2. Was microbiome affected by diet?  
3. Was there a difference between the KO and WT?  
4. If there was a change in microbiome composition, what functional changes did it carry? What are the essential functions of the bacteria affected by the treatment and how can this be shown in vivo (metabolites, inflammation markers, etc.)?

# Data preprocessing
## Raw Data 
FastQ files were downloaded from [this Rutgers Box location](https://rutgers.app.box.com/folder/90143462291). A total of 144 files (2 per sample, pair-ended) and a pair of undetermined reads were downloaded. 

## Script
This script (***nrf2ubiome_dada2_sep2019_v1.Rmd***) was developed using [DADA2 Pipeline Tutorial (1.12)](https://benjjneb.github.io/dada2/tutorial.html) with tips and tricks from the [University of Maryland Shool of Medicine Institute for Genome Sciences (IGS)](http://www.igs.umaryland.edu/) [Microbiome Analysis Workshop (April 8-11, 2019)](http://www.igs.umaryland.edu/education/wkshp_metagenome.php). The output of the DADA2 script (***data_may2019/ps_sep2019.RData***) is explored in this document.

# Meta data: sample description

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuIyBMb2FkIGRhdGEtLS0tXG4jIENvdW50c1xubG9hZChcImRhdGFfc2VwMjAxOS9wc19zZXAyMDE5LlJEYXRhXCIpXG5cbiMgVGF4b25vbXlcbmxvYWQoXCJkYXRhX3NlcDIwMTkvdGF4YS5SRGF0YVwiKVxudGF4YSA8LSBkYXRhLnRhYmxlKHNlcTE2cyA9IHJvd25hbWVzKHRheGEpLFxuICAgICAgICAgICAgICAgICAgIHRheGEpXG5gYGAifQ== -->

```r
# Load data----
# Counts
load("data_sep2019/ps_sep2019.RData")

# Taxonomy
load("data_sep2019/taxa.RData")
taxa <- data.table(seq16s = rownames(taxa),
                   taxa)

NOTE: correction to the meta-data! (11/15/2019)

correct_samples <- fread("data_sep2019/16s metadata Sep-2019.csv")
ps_sep2019@sam_data$DSS <- correct_samples$DSS

1 Samples

ps_sep2019@sam_data$Genotype_Week <- paste(ps_sep2019@sam_data$genotype,
                                           ps_sep2019@sam_data$time,
                                           sep = "_")
ps_sep2019@sam_data$ID <- factor(paste0(ps_sep2019@sam_data$mice_num,
                                        ps_sep2019@sam_data$cage))

ps_sep2019@sam_data$TREATMENT <- paste0(ps_sep2019@sam_data$DSS,
                                        ps_sep2019@sam_data$PEITC,
                                        ps_sep2019@sam_data$cranberry)
ps_sep2019@sam_data$TREATMENT <- factor(ps_sep2019@sam_data$TREATMENT,
                                        levels = c("000",
                                                   "100",
                                                   "110",
                                                   "101"),
                                        labels = c("Naive",
                                                   "DSS",
                                                   "DSS+PEITC",
                                                   "DSS+Cranberry"))

samples <- ps_sep2019@sam_data
datatable(samples,
          options = list(pageLength = nrow(samples)))

2 Prune data

The OTUs were mapped to Bacteria (96.07%), Eukaryota (2.95%) and Archea (0.03%) kingdoms, and 75 OTUs (0.95%) undefined.

The total of 7,867 unique sequences were found. Out of those, 7,558 were mapped to bacterial genomes.

dim(ps_sep2019@otu_table@.Data)
[1]   72 7867
# Remove OTU not mapped to Bacteria
ps0 <- subset_taxa(ps_sep2019, 
                   Kingdom == "Bacteria")
dim(ps0@otu_table@.Data)
[1]   72 7558

Out of the 7,558 OTUs 7,247 belonged to 12 Phyla. 311 of the OTUs (or 4.11% of bacterial OTUs) could not be mapped to a phylum.

t2 <- data.table(table(tax_table(ps0)[, "Phylum"],
                                  exclude = NULL))
t2$V1[is.na(t2$V1)] <- "Unknown"
setorder(t2, -N)
t2[, pct := N/sum(N)]
setorder(t2, -N)

colnames(t2) <- c("Phylum",
                  "Number of OTUs",
                  "Percent of OTUs")

datatable(t2,
          rownames = FALSE,
          caption = "Number of Bacterial OTUs by Phylum",
          class = "cell-border stripe",
          options = list(search = FALSE,
                         pageLength = nrow(t2))) %>%
  formatCurrency(columns = 2,
                 currency = "",
                 mark = ",",
                 digits = 0) %>%
  formatPercentage(columns = 3,
                   digits = 2)

3 OTU table (first 10 rows)

4 Total counts per sample (i.e. sequencing depth)

t1 <- colSums(otu[, 7:ncol(otu)])
t1 <- data.table(SAMPLE_NAME = names(t1),
                 Total = t1)

t2 <- data.table(SAMPLE_NAME = rownames(samples),
                 ID = samples$ID,
                 CAGE = samples$cage,
                 TREATMENT = samples$TREATMENT,
                 Genotype = samples$genotype,
                 WEEK = samples$time)

smpl <- merge(t1,
              t2,
              by = "SAMPLE_NAME")

p1 <- ggplot(smpl,
             aes(x = SAMPLE_NAME,
                 y = Total,
                 fill = TREATMENT,
                 colour = WEEK)) +
  facet_wrap(~ Genotype,
             scale = "free_x") +
  geom_bar(stat = "identity") +
  scale_x_discrete("") +
  scale_y_continuous("Number of Reads") +
  scale_fill_discrete("Treatment") +
  theme(axis.text.x = element_text(angle = 45,
                                   hjust = 1)) 
ggplotly(p1)

5 Richness (Alpha diversity)

Shannon index (aka Shannon enthrophy) is calculated as:
H’ = -sum(1 to R)p(i)ln(p(i)) When there is exactly 1 type of data (e.g. a single species in the sample), H’=0. The opposite scenario is when there are R>1 species present in the sample in the exact same amounts and H’=ln(R).

Shannon’s diversity index was calculated for each sample and ploted over time using the 7,764 from the 13 Phylum above.

shannon.ndx <- estimate_richness(ps0,
                                 measures = "Shannon")

shannon.ndx <- data.table(SAMPLE_NAME = rownames(shannon.ndx),
                          shannon.ndx)

smpl <- merge(smpl,
              shannon.ndx,
              by = "SAMPLE_NAME")

p1 <- ggplot(smpl,
             aes(x = Total,
                 y = Shannon,
                 fill = Genotype,
                 shape = WEEK)) +
  geom_point(size = 2) +
  scale_shape_manual(breaks = unique(smpl$WEEK),
                     values = 21:23)

tiff(filename = "tmp/shannon_vs_depth.tiff",
     height = 5,
     width = 6,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p1)
graphics.off()

ggplotly(p1)

Even though estimate_richness function does not adjust for the sequencing depth, there is no correlation between the index and the sample’s sequecing depth. Proceed with the comparison.

6 Shannon idex over time

p1 <- plot_richness(ps0,
                    x = "time", 
                    measures = "Shannon") +
  facet_wrap(~ genotype) +
  geom_line(aes(group = ID),
            color = "black") +
  geom_point(aes(fill = TREATMENT),
             shape = 21,
             size = 3,
             color = "black") +
  scale_x_discrete("") +
  theme(axis.text.x = element_text(angle = 30,
                                   hjust = 1,
                                   vjust = 1))

ggplotly(p = p1,
         tooltip = c("ID",
                     "value"))


p1 <- p1 + 
  scale_fill_discrete("") +
  theme(legend.position = "top")

tiff(filename = "tmp/shannon.tiff",
     height = 4,
     width = 5,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p1)
graphics.off()

The plot above suggests that the largest differences in alpha diversity (as measured by Shannon’s index) are in genotype.

Test if the richness changed between the baseline and Week 8.

smpl$TREATMENT <- factor(smpl$TREATMENT,
                         levels = c("DSS",
                                    "Naive",
                                    "DSS+PEITC",
                                    "DSS+Cranberry"))

tmp <- droplevels(smpl[WEEK != "week1"])

m1 <- lm(Shannon  ~ WEEK*(TREATMENT + Genotype),
         # offset = Total,
         data = tmp)
summary(m1)

Call:
lm(formula = Shannon ~ WEEK * (TREATMENT + Genotype), data = tmp)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.316186 -0.091027  0.007886  0.110704  0.293230 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)
(Intercept)                       5.94987    0.07064  84.233  < 2e-16
WEEKweek8                         0.01158    0.09989   0.116   0.9084
TREATMENTNaive                    0.14581    0.08935   1.632   0.1109
TREATMENTDSS+PEITC               -0.03923    0.08935  -0.439   0.6631
TREATMENTDSS+Cranberry           -0.22582    0.08935  -2.527   0.0158
Genotypewidetype                 -0.54156    0.06318  -8.572 2.06e-10
WEEKweek8:TREATMENTNaive          0.01181    0.12636   0.093   0.9261
WEEKweek8:TREATMENTDSS+PEITC      0.01652    0.12636   0.131   0.8966
WEEKweek8:TREATMENTDSS+Cranberry  0.21535    0.12636   1.704   0.0965
WEEKweek8:Genotypewidetype        0.23085    0.08935   2.584   0.0137
                                    
(Intercept)                      ***
WEEKweek8                           
TREATMENTNaive                      
TREATMENTDSS+PEITC                  
TREATMENTDSS+Cranberry           *  
Genotypewidetype                 ***
WEEKweek8:TREATMENTNaive            
WEEKweek8:TREATMENTDSS+PEITC        
WEEKweek8:TREATMENTDSS+Cranberry .  
WEEKweek8:Genotypewidetype       *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1548 on 38 degrees of freedom
Multiple R-squared:  0.7845,    Adjusted R-squared:  0.7335 
F-statistic: 15.37 on 9 and 38 DF,  p-value: 3.671e-10
m2 <- lmer(Shannon  ~ WEEK*(TREATMENT + Genotype) + (1 | ID),
           # offset = Total,
           data = tmp)
summary(m2)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: Shannon ~ WEEK * (TREATMENT + Genotype) + (1 | ID)
   Data: tmp

REML criterion at convergence: -22.2

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-1.53721 -0.47495  0.06753  0.44489  1.53874 

Random effects:
 Groups   Name        Variance Std.Dev.
 ID       (Intercept) 0.01259  0.1122  
 Residual             0.01136  0.1066  
Number of obs: 48, groups:  ID, 24

Fixed effects:
                                 Estimate Std. Error       df t value
(Intercept)                       5.94987    0.07064 29.76837  84.233
WEEKweek8                         0.01158    0.06879 19.00000   0.168
TREATMENTNaive                    0.14581    0.08935 29.76837   1.632
TREATMENTDSS+PEITC               -0.03923    0.08935 29.76837  -0.439
TREATMENTDSS+Cranberry           -0.22582    0.08935 29.76837  -2.527
Genotypewidetype                 -0.54156    0.06318 29.76837  -8.572
WEEKweek8:TREATMENTNaive          0.01181    0.08701 19.00000   0.136
WEEKweek8:TREATMENTDSS+PEITC      0.01652    0.08701 19.00000   0.190
WEEKweek8:TREATMENTDSS+Cranberry  0.21535    0.08701 19.00000   2.475
WEEKweek8:Genotypewidetype        0.23085    0.06152 19.00000   3.752
                                 Pr(>|t|)    
(Intercept)                       < 2e-16 ***
WEEKweek8                         0.86814    
TREATMENTNaive                    0.11322    
TREATMENTDSS+PEITC                0.66379    
TREATMENTDSS+Cranberry            0.01704 *  
Genotypewidetype                 1.55e-09 ***
WEEKweek8:TREATMENTNaive          0.89350    
WEEKweek8:TREATMENTDSS+PEITC      0.85139    
WEEKweek8:TREATMENTDSS+Cranberry  0.02291 *  
WEEKweek8:Genotypewidetype        0.00135 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                     (Intr) WEEKw8 TREATMENTN TREATMENTDSS+P
WEEKweek8            -0.487                                 
TREATMENTNv          -0.632  0.308                          
TREATMENTDSS+P       -0.632  0.308  0.500                   
TREATMENTDSS+C       -0.632  0.308  0.500      0.500        
Gentypwdtyp          -0.447  0.218  0.000      0.000        
WEEK8:TREATMENTN      0.308 -0.632 -0.487     -0.243        
WEEK8:TREATMENTDSS+P  0.308 -0.632 -0.243     -0.487        
WEEK8:TREATMENTDSS+C  0.308 -0.632 -0.243     -0.243        
WEEKwk8:Gnt           0.218 -0.447  0.000      0.000        
                     TREATMENTDSS+C Gntypw WEEK8:TREATMENTN
WEEKweek8                                                  
TREATMENTNv                                                
TREATMENTDSS+P                                             
TREATMENTDSS+C                                             
Gentypwdtyp           0.000                                
WEEK8:TREATMENTN     -0.243          0.000                 
WEEK8:TREATMENTDSS+P -0.243          0.000  0.500          
WEEK8:TREATMENTDSS+C -0.487          0.000  0.500          
WEEKwk8:Gnt           0.000         -0.487  0.000          
                     WEEK8:TREATMENTDSS+P WEEK8:TREATMENTDSS+C
WEEKweek8                                                     
TREATMENTNv                                                   
TREATMENTDSS+P                                                
TREATMENTDSS+C                                                
Gentypwdtyp                                                   
WEEK8:TREATMENTN                                              
WEEK8:TREATMENTDSS+P                                          
WEEK8:TREATMENTDSS+C  0.500                                   
WEEKwk8:Gnt           0.000                0.000              

7 Calculate change in Shannon index from baseline

dd <- smpl
dd[, delta := Shannon - Shannon[WEEK == "baseline"],
   by = ID]
dd$diff <- paste(dd$WEEK,
                 "-baseline",
                 sep = "")

dd <- dd[WEEK != "baseline",]

p1 <- ggplot(dd,
             aes(x = TREATMENT,
                 y = delta,
                 fill = Genotype)) +
  facet_wrap(~ diff) +
  geom_hline(yintercept = 0,
             linetype = "dashed") +
  geom_point(position = position_dodge(0.3),
             shape = 21,
             size = 3) +
  scale_y_continuous("Shannon Index Percent Change from Baseline") +
  theme(axis.text.x = element_text(angle = 45,
                                   hjust = 1))
print(p1)


dd$TREATMENT <- factor(dd$TREATMENT,
                        levels = c("DSS",
                                   "Naive",
                                   "DSS+PEITC",
                                   "DSS+Cranberry"))
dd$Genotype <- factor(dd$Genotype,
                       levels = c("widetype",
                                  "nrf2KO"))

m1 <- lm(delta ~ TREATMENT*Genotype,
         data = dd)
summary(m1)

Call:
lm(formula = delta ~ TREATMENT * Genotype, data = dd)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.40513 -0.09560 -0.02012  0.09568  0.35517 

Coefficients:
                                      Estimate Std. Error t value
(Intercept)                            0.25142    0.07286   3.451
TREATMENTNaive                        -0.04426    0.10303  -0.430
TREATMENTDSS+PEITC                    -0.15777    0.10303  -1.531
TREATMENTDSS+Cranberry                 0.04463    0.10303   0.433
Genotypenrf2KO                        -0.18412    0.10303  -1.787
TREATMENTNaive:Genotypenrf2KO         -0.02851    0.14571  -0.196
TREATMENTDSS+PEITC:Genotypenrf2KO      0.24747    0.14571   1.698
TREATMENTDSS+Cranberry:Genotypenrf2KO  0.07927    0.14571   0.544
                                      Pr(>|t|)   
(Intercept)                            0.00133 **
TREATMENTNaive                         0.66985   
TREATMENTDSS+PEITC                     0.13358   
TREATMENTDSS+Cranberry                 0.66720   
Genotypenrf2KO                         0.08153 . 
TREATMENTNaive:Genotypenrf2KO          0.84586   
TREATMENTDSS+PEITC:Genotypenrf2KO      0.09721 . 
TREATMENTDSS+Cranberry:Genotypenrf2KO  0.58946   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1785 on 40 degrees of freedom
Multiple R-squared:  0.249, Adjusted R-squared:  0.1176 
F-statistic: 1.894 on 7 and 40 DF,  p-value: 0.09608
# No significant interactions, proceed with 2-way analysis
m2 <- lm(delta ~ TREATMENT + Genotype,
         data = dd)
summary(m2)

Call:
lm(formula = delta ~ TREATMENT + Genotype, data = dd)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.49158 -0.09742 -0.01290  0.11101  0.35281 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)             0.21414    0.05849   3.661 0.000683 ***
TREATMENTNaive         -0.05851    0.07399  -0.791 0.433377    
TREATMENTDSS+PEITC     -0.03404    0.07399  -0.460 0.647813    
TREATMENTDSS+Cranberry  0.08427    0.07399   1.139 0.261014    
Genotypenrf2KO         -0.10956    0.05232  -2.094 0.042176 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1812 on 43 degrees of freedom
Multiple R-squared:  0.1674,    Adjusted R-squared:  0.08999 
F-statistic: 2.162 on 4 and 43 DF,  p-value: 0.08947

At Week 8 there was significantly smaller increase of alpha diversity from baseline in Nrf2 KO compared to WT, and in DSS+Cranberry compared to DSS only.

8 Load aminoacids

aa <- fread("data_sep2019/sep2019_aminoacids.csv")

aa <- aa[!is.na(ID), ]
aa$ID <- paste0(aa$ID,
                aa$CAGE)

smpl1 <- unique(smpl[, c("ID",
                            "TREATMENT",
                            "Genotype")])
smpl1$ID <- as.character(smpl1$ID)
aa <- merge(smpl1,
            aa,
            by = "ID")
aa[, trt_week := paste(TREATMENT,
                       WEEK,
                       sep = "_")]
aa$trt_week <- factor(aa$trt_week,
                      levels = c("Naive_week2",
                                 "Naive_week6",
                                 "DSS_week2",
                                 "DSS_week6",
                                 "DSS+Cranberry_week2",
                                 "DSS+Cranberry_week6" ,
                                 "DSS+PEITC_week2",
                                 "DSS+PEITC_week6"))
for (i in 8:(ncol(aa) - 1)) {
  tmp <- aa[, c(1, 3, 7, ncol(aa), i), with = FALSE]
  colnames(tmp)[5] <- "Y"
  p1 <- ggplot(tmp,
               aes(x = trt_week,
                   y = Y,
                   fill = Genotype,
                   group = ID)) +
    geom_line(position = position_dodge(0.3)) +
    geom_point(shape = 21,
               size = 3,
               position = position_dodge(0.3)) +
    scale_x_discrete("") +
    scale_y_continuous(colnames(aa)[i]) +
    theme(axis.text.x = element_text(angle = 45,
                                     hjust = 1))
  # tiff(filename = paste0("tmp/",
  #                        colnames(aa)[i],
  #                        ".tiff"),
  #      height = 4,
  #      width = 5,
  #      units = "in",
  #      res = 600,
  #      compression = "lzw+p")
  # print(p1)
  # graphics.off()
  
  print(p1)
}

9 Aminoacid data PCA

dt_pca <- aa[, Alanine:glutamine]

m1 <- prcomp(dt_pca)
summary(m1)
Importance of components:
                          PC1    PC2     PC3     PC4     PC5     PC6
Standard deviation     4.8108 2.5833 1.78182 1.13495 0.93367 0.84949
Proportion of Variance 0.6276 0.1810 0.08609 0.03493 0.02364 0.01957
Cumulative Proportion  0.6276 0.8086 0.89466 0.92959 0.95323 0.97280
                           PC7     PC8     PC9    PC10    PC11    PC12
Standard deviation     0.62035 0.49052 0.35960 0.26786 0.22940 0.20322
Proportion of Variance 0.01044 0.00652 0.00351 0.00195 0.00143 0.00112
Cumulative Proportion  0.98323 0.98976 0.99326 0.99521 0.99663 0.99775
                         PC13    PC14    PC15    PC16    PC17    PC18
Standard deviation     0.1486 0.13250 0.11932 0.11154 0.08896 0.07274
Proportion of Variance 0.0006 0.00048 0.00039 0.00034 0.00021 0.00014
Cumulative Proportion  0.9983 0.99883 0.99922 0.99955 0.99977 0.99991
                          PC19    PC20
Standard deviation     0.05110 0.02565
Proportion of Variance 0.00007 0.00002
Cumulative Proportion  0.99998 1.00000
# Select PC-s to pliot (PC1 & PC2)
choices <- 1:2
# Scores, i.e. points (df.u)
dt.scr <- data.table(m1$x[, choices])
# Add grouping variable
dt.scr$grp <- aa$trt_week
dt.scr$TREATMENT <- aa$TREATMENT
dt.scr$WEEK <- aa$WEEK
dt.scr

# Loadings, i.e. arrows (df.v)
dt.rot <- as.data.frame(m1$rotation[, choices])
dt.rot$feat <- rownames(dt.rot)
dt.rot <- data.table(dt.rot)
dt.rot

dt.load <- melt.data.table(dt.rot,
                           id.vars = "feat",
                           measure.vars = 1:2,
                           variable.name = "pc",
                           value.name = "loading")
dt.load$feat <- factor(dt.load$feat,
                       levels = unique(dt.load$feat))
# Plot loadings
p0 <- ggplot(data = dt.load,
             aes(x = feat,
                 y = loading)) +
  facet_wrap(~ pc,
             nrow = 2) +
  geom_bar(stat = "identity") +
  ggtitle("PC Loadings") +
  theme(plot.title = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 45,
                                   hjust = 1))
tiff(filename = "tmp/pc.1.2_loadings.tiff",
     height = 5,
     width = 8,
     units = 'in',
     res = 300,
     compression = "lzw+p")
print(p0)
graphics.off()

print(p0)

# Axis labels
u.axis.labs <- paste(colnames(dt.rot)[1:2], 
                     sprintf('(%0.1f%% explained var.)', 
                             100*m1$sdev[choices]^2/sum(m1$sdev^2)))
u.axis.labs
[1] "PC1 (62.8% explained var.)" "PC2 (18.1% explained var.)"
# Based on Figure p0, keep only a few variables with high loadings in PC1 and PC2----
# var.keep.ndx <- which(dt.rot$feat %in% c(...))
# Or select all
# var.keep.ndx <- 3:ncol(dt1)
# Use dt.rot[var.keep.ndx,] and dt.rot$feat[var.keep.ndx]
p1 <- ggplot(data = dt.rot,
             aes(x = PC1,
                 y = PC2)) +
  coord_equal() +
  geom_point(data = dt.scr,
             aes(fill = grp),
             shape = 21,
             size = 2,
             alpha = 0.5) +
  geom_segment(aes(x = 0,
                   y = 0,
                   xend = 10*PC1,
                   yend = 10*PC2),
               arrow = arrow(length = unit(1/2, 'picas')),
               size = 1.2, 
               color = "black") +
  geom_text(aes(x = 11*PC1,
                y = 11*PC2,
                label = dt.rot$feat),
            # size = 5,
            hjust = 0.5) +
  scale_x_continuous(u.axis.labs[1]) +
  scale_y_continuous(u.axis.labs[2]) +
  scale_fill_discrete(name = "Group") +
  ggtitle("Biplot of Aminoacids") +
  theme(plot.title = element_text(hjust = 0.5,
                                  size = 20))
tiff(filename = "tmp/aminoacids_biplot.tiff",
     height = 10,
     width = 10,
     units = 'in',
     res = 300,
     compression = "lzw+p")
print(p1)
graphics.off()

ggplotly(p1)

p2 <- ggplot(data = dt.rot,
             aes(x = PC1,
                 y = PC2)) +
  coord_equal() +
  geom_point(data = dt.scr,
             aes(fill = WEEK),
             shape = 21,
             size = 2,
             alpha = 0.5) +
  geom_segment(aes(x = 0,
                   y = 0,
                   xend = 10*PC1,
                   yend = 10*PC2),
               arrow = arrow(length = unit(1/2, 'picas')),
               size = 1.2, 
               color = "black") +
  geom_text(aes(x = 11*PC1,
                y = 11*PC2,
                label = dt.rot$feat),
            # size = 5,
            hjust = 0.5) +
  scale_x_continuous(u.axis.labs[1]) +
  scale_y_continuous(u.axis.labs[2]) +
  scale_fill_discrete(name = "Week") +
  ggtitle("Biplot of Aminoacids") +
  theme(plot.title = element_text(hjust = 0.5,
                                  size = 20))
tiff(filename = "tmp/aminoacids_by_week_biplot.tiff",
     height = 10,
     width = 10,
     units = 'in',
     res = 300,
     compression = "lzw+p")
print(p2)
graphics.off()

ggplotly(p2)

p2 <- ggplot(data = dt.rot,
             aes(x = PC1,
                 y = PC2)) +
  coord_equal() +
  geom_point(data = dt.scr,
             aes(fill = TREATMENT),
             shape = 21,
             size = 2,
             alpha = 0.5) +
  geom_segment(aes(x = 0,
                   y = 0,
                   xend = 10*PC1,
                   yend = 10*PC2),
               arrow = arrow(length = unit(1/2, 'picas')),
               size = 1.2, 
               color = "black") +
  geom_text(aes(x = 11*PC1,
                y = 11*PC2,
                label = dt.rot$feat),
            # size = 5,
            hjust = 0.5) +
  scale_x_continuous(u.axis.labs[1]) +
  scale_y_continuous(u.axis.labs[2]) +
  scale_fill_discrete(name = "Treatment") +
  ggtitle("Biplot of Aminoacids") +
  theme(plot.title = element_text(hjust = 0.5,
                                  size = 20))
tiff(filename = "tmp/aminoacids_by_trt_biplot.tiff",
     height = 10,
     width = 10,
     units = 'in',
     res = 300,
     compression = "lzw+p")
print(p2)
graphics.off()

ggplotly(p2)

10 Remove unmapped OTUs

The 311 unmapped OTUs were removed from further analysis (with 7,247 OTUs left).

ps1 <- subset_taxa(ps0, 
                   !is.na(Phylum))
dim(ps1@otu_table@.Data)
[1]   72 7247

11 Counts at Phylum level

12 Relative abundance (%) at Phylum level

Remove phyla with relative abundance of >= 1% in less than 10% of samples.

t1 <- data.table(Phylum = ra_p$Phylum,
                 `Number of Samples` = rowSums(ra_p[, 2:ncol(ra_p)] >= 0.01))
t1$`Percent Samples` <-  t1$`Number of Samples`/72

setorder(t1, -`Number of Samples`)
datatable(t1,
          rownames = FALSE,
          caption = "Taxonomic  count table",
          class = "cell-border stripe",
          options = list(search = FALSE,
                         pageLength = nrow(t1))) %>%
  formatPercentage(columns = 3,
                   digits = 1)

We will remove Chlamydiae from this analysis.

XX OTUs, down from YY OTUs in the previous table.

13 Relative Abundance in Samples at Different Taxonomic Ranks

13.1 1. Class

mu$Trt_Genotype <- factor(paste(mu$Treatment,
                          mu$Genotype,
                          sep = "_"))

p0 <- ggplot(mu,
             aes(x = Week,
                 y = x,
                 group = Trt_Genotype)) +
  facet_wrap(~ Class,
             scale = "free_y") +
  geom_line(position = position_dodge(0.3)) +
  geom_point(aes(fill = Trt_Genotype),
             shape = 21,
             size = 2,
             alpha = 0.5,
             position = position_dodge(0.3)) +
  scale_x_discrete("") +
  scale_y_continuous("Relative Abundance (%)") +
  theme(legend.position = "top",
        axis.text.x = element_text(angle = 45,
                                   hjust = 1))

tiff(filename = "tmp/wt_class_over_time.tiff",
     height = 5,
     width = 7,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p0)
graphics.off()

print(p0)
p1 <- ggplot(mu,
             aes(x = x,
                 y = Class,
                 color = Trt_Genotype,
                 shape = Week)) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_continuous("Relative Abundance (%)") +
  theme(legend.position = "top")

tiff(filename = "tmp/wt_class_ra.tiff",
     height = 4,
     width = 7,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p1)
graphics.off()

ggplotly(p1)

13.2 2. Order

mu$Trt_Genotype <- factor(paste(mu$Treatment,
                                mu$Genotype,
                                sep = "_"))

p0 <- ggplot(mu,
             aes(x = Week,
                 y = x,
                 group = Trt_Genotype)) +
  facet_wrap(~ Order,
             scale = "free_y") +
  geom_line(position = position_dodge(0.3)) +
  geom_point(aes(fill = Trt_Genotype),
             shape = 21,
             size = 2,
             alpha = 0.5,
             position = position_dodge(0.3)) +
  scale_x_discrete("") +
  scale_y_continuous("Relative Abundance (%)") +
  theme(legend.position = "top",
        axis.text.x = element_text(angle = 45,
                                   hjust = 1))

tiff(filename = "tmp/wt_Order_over_time.tiff",
     height = 5,
     width = 7,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p0)
graphics.off()

print(p0)
p1 <- ggplot(mu,
             aes(x = x,
                 y = Order,
                 color = Trt_Genotype,
                 shape = Week)) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_continuous("Relative Abundance (%)") +
  theme(legend.position = "top")

tiff(filename = "tmp/wt_Order_ra.tiff",
     height = 4,
     width = 7,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p1)
graphics.off()

ggplotly(p1)

13.3 3. Family

NOTE: only the first 24 families had large enough counts - ploting only them.

mu$Trt_Genotype <- factor(paste(mu$Treatment,
                                mu$Genotype,
                                sep = "_"))
mu1 <- droplevels(mu[Family %in% levels(mu$Family)[nlevels(mu$Family):(nlevels(mu$Family) - 24)], ])

p0 <- ggplot(mu1,
             aes(x = Week,
                 y = x,
                 group = Trt_Genotype)) +
  facet_wrap(~ Family,
             scale = "free_y") +
  geom_line(position = position_dodge(0.3)) +
  geom_point(aes(fill = Trt_Genotype),
             shape = 21,
             size = 2,
             alpha = 0.5,
             position = position_dodge(0.3)) +
  scale_x_discrete("") +
  scale_y_continuous("Relative Abundance (%)") +
  theme(legend.position = "top",
        axis.text.x = element_text(angle = 45,
                                   hjust = 1))

tiff(filename = "tmp/wt_Family_over_time.tiff",
     height = 7,
     width = 9,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p0)
graphics.off()

print(p0)
p1 <- ggplot(mu1,
             aes(x = x,
                 y = Family,
                 color = Trt_Genotype,
                 shape = Week)) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_continuous("Relative Abundance (%)") +
  theme(legend.position = "top")

tiff(filename = "tmp/wt_Family_ra.tiff",
     height = 4,
     width = 7,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p1)
graphics.off()

ggplotly(p1)

13.4 4. Genus

mu$Trt_Genotype <- factor(paste(mu$Treatment,
                                mu$Genotype,
                                sep = "_"))
mu1 <- droplevels(mu[Genus %in% levels(mu$Genus)[nlevels(mu$Genus):(nlevels(mu$Genus) - 35)], ])

p0 <- ggplot(mu1,
             aes(x = Week,
                 y = x,
                 group = Trt_Genotype)) +
  facet_wrap(~ Genus,
             scale = "free_y") +
  geom_line(position = position_dodge(0.3)) +
  geom_point(aes(fill = Trt_Genotype),
             shape = 21,
             size = 2,
             alpha = 0.5,
             position = position_dodge(0.3)) +
  scale_x_discrete("") +
  scale_y_continuous("Relative Abundance (%)") +
  theme(legend.position = "top",
        axis.text.x = element_text(angle = 45,
                                   hjust = 1))

tiff(filename = "tmp/wt_Genus_over_time.tiff",
     height = 9,
     width = 12,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p0)
graphics.off()

print(p0)
p1 <- ggplot(mu1,
             aes(x = x,
                 y = Genus,
                 color = Trt_Genotype,
                 shape = Week)) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_continuous("Relative Abundance (%)") +
  theme(legend.position = "top")

tiff(filename = "tmp/wt_Genus_ra.tiff",
     height = 9,
     width = 9,
     units = "in",
     res = 600,
     compression = "lzw+p")
print(p1)
graphics.off()

ggplotly(p1)

14 Session Information

sessionInfo()
LS0tDQp0aXRsZTogIkRhdGEgVmlzdWFsaXphdGlvbiBvZiBXVCBhbmQgTnJmMiBLTyAoLS8tKSBCTDYgUEVJVEMgb3IgQ3JhbmJlcnJ5IFRyZWF0ZWQgTWljZSAxNlMgTWljcm9iaW9tZSBEYXRhIEFuYWx5c2lzLCBTZXB0ZW1iZXIgMjAxOSBCYXRjaCINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQotLS0NCkRhdGU6IGByIGRhdGUoKWAgICAgIA0KU2NpZW50aXN0OiBbUmFuIFlpbl0obWFpbHRvOnJ5MTQ3QHNjYXJsZXRtYWlsLnJ1dGdlcnMuZWR1KSAgICAgIA0KU2VxdWVuY2luZyAoV2Frc21hbik6IFtEaWJ5ZW5kdSBLdW1hcl0obWFpbHRvOmRrQHdha3NtYW4ucnV0Z2Vycy5lZHUpICAgICAgDQpTdGF0aXN0aWNzOiBbRGF2aXQgU2FyZ3N5YW5dKG1haWx0bzpzYXJnZGF2aWRAZ21haWwuY29tKSAgICAgIA0KUHJpbmNpcGFsIEludmVzdGlnYXRvcjogW0FoLU5nIEtvbmddKG1haWx0bzprb25ndEBwaGFybWFjeS5ydXRnZXJzLmVkdSkgDQoNCmBgYHt9DQojIFRheG9ub21pYyBSYW5rczoNCiMgKipLKippbmcgKipQKipoaWxsaXAgKipDKiphbiBuKipPKip0ICoqRioqaW5kICoqRyoqcmVlbiAqKlMqKm9ja3MNCiMgKiBLaW5nZG9tICAgICAgICAgICAgICAgIA0KIyAqIFBoeWx1bSAgICAgICAgICAgICAgICAgICAgDQojICogQ2xhc3MgICAgICAgICAgICAgICAgICAgDQojICogT3JkZXIgICAgICAgICAgICAgICAgICAgDQojICogRmFtaWx5ICAgICANCiMgKiBHZW51cyAgICAgDQojICogU3BlY2llcyAgDQpgYGANCg0KYGBge3Igc2V0dXB9DQojIG9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLA0KIyAgICAgICAgIHNjaXBlbiA9IDk5OSkNCg0KIyAjIEluY3JlYXNlIG1tZW1vcnkgc2l6ZSB0byA2NCBHYi0tLS0NCiMgaW52aXNpYmxlKHV0aWxzOjptZW1vcnkubGltaXQoNjU1MzYpKQ0KDQoNCiMgc3RyKGtuaXRyOjpvcHRzX2NodW5rJGdldCgpKQ0KIyAjIE5PVEU6IHRoZSBiZWxvdyBkb2VzIG5vdCB3b3JrIQ0KIyBrbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCANCiMgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiMgICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwNCiMgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gRkFMU0UpDQoNCiMgcmVxdWlyZShrbml0cikNCiMgcmVxdWlyZShrYWJsZUV4dHJhKQ0KcmVxdWlyZShwaHlsb3NlcSkNCiMgcmVxdWlyZShzaGlueSkNCg0KcmVxdWlyZShkYXRhLnRhYmxlKQ0KcmVxdWlyZShnZ3Bsb3QyKQ0KcmVxdWlyZShwbG90bHkpDQpyZXF1aXJlKERUKQ0KcmVxdWlyZShsbWVyVGVzdCkNCg0Kc291cmNlKCJzb3VyY2UvZnVuY3Rpb25zX21heTIwMTkuUiIpDQoNCiMgT24gV2luZG93cyBzZXQgbXVsdGl0aHJlYWQ9RkFMU0UtLS0tDQptdCA8LSBUUlVFDQpgYGANCg0KIyBJbnRyb2R1Y3Rpb24NCkM1N0JMLzYgd2lsZC10eXBlIChXVCkgYW5kIE5yZi0yIGRvdWJsZS1rbm9jay1vdXQgKEtPIC0vLSkgbWljZSB3ZXJlIGdpdmVuIDItd2VlayBtaWNyb2Jpb21lIHN0YWJpbGl6YXRpb24gcHJvY2VzcyB1c2luZyBBSU45M00gZGlldCBhbmQgOCBtb3JlIHdlZWtzIHRvIHRyZWF0IHdpdGggZWl0aGVyIEFJTjkzTSBvciBBSU45M00gNSUgUEVJVEMgZGlldC4gRmVjYWwgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCB3ZWVrbHksIGltbWVkaWF0ZWx5IGZyb3plbiBpbiBsaXF1aWQgbml0cm9nZW4gYW5kIHN0b3JlZCBhdCAtODBeb15DLiBTZXJ1bSwgY2VjYWwsIGNvbG9uIGVwaXRoZWxpYWwgYW5kIHdob2xlIGNvbG9uIHRpc3N1ZXMgYXQgd2VlayAxMCB3ZXJlIGFsc28gY29sbGVjdGVkIGZvciBmdXJ0aGVyIGFuYWx5c2VzLiBCYXNlbGluZSwgd2VlayAxIGFuZCA0IGZlY2FsIHNhbXBsZXMgd2VyZSBzZWxlY3RlZCBmb3IgMTZzIHJSTkEgc2VxdWVuY2luZy4gIA0KICANClRoaXMgZG9jdW1lbnQgZXhhbWluZXMgcmVzdWx0cyBmcm9tIHRoZSBXVCBtaWNlIHNhbXBsZXMuICANCiAgDQpXZSB3aWxsIGF0dGFtcHQgdG8gYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOiAgDQoxLiBEaWQgbWljcm9iaW9tZSBjaGFuZ2Ugb3ZlciB0aW1lPyAgDQoyLiBXYXMgbWljcm9iaW9tZSBhZmZlY3RlZCBieSBkaWV0PyAgDQozLiBXYXMgdGhlcmUgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIEtPIGFuZCBXVD8gIA0KNC4gSWYgdGhlcmUgd2FzIGEgY2hhbmdlIGluIG1pY3JvYmlvbWUgY29tcG9zaXRpb24sIHdoYXQgZnVuY3Rpb25hbCBjaGFuZ2VzIGRpZCBpdCBjYXJyeT8gV2hhdCBhcmUgdGhlIGVzc2VudGlhbCBmdW5jdGlvbnMgb2YgdGhlIGJhY3RlcmlhIGFmZmVjdGVkIGJ5IHRoZSB0cmVhdG1lbnQgYW5kIGhvdyBjYW4gdGhpcyBiZSBzaG93biBpbiB2aXZvIChtZXRhYm9saXRlcywgaW5mbGFtbWF0aW9uIG1hcmtlcnMsIGV0Yy4pPw0KDQojIERhdGEgcHJlcHJvY2Vzc2luZw0KIyMgUmF3IERhdGEgDQpGYXN0USBmaWxlcyB3ZXJlIGRvd25sb2FkZWQgZnJvbSBbdGhpcyBSdXRnZXJzIEJveCBsb2NhdGlvbl0oaHR0cHM6Ly9ydXRnZXJzLmFwcC5ib3guY29tL2ZvbGRlci85MDE0MzQ2MjI5MSkuIEEgdG90YWwgb2YgMTQ0IGZpbGVzICgyIHBlciBzYW1wbGUsIHBhaXItZW5kZWQpIGFuZCBhIHBhaXIgb2YgdW5kZXRlcm1pbmVkIHJlYWRzIHdlcmUgZG93bmxvYWRlZC4gDQoNCiMjIFNjcmlwdA0KVGhpcyBzY3JpcHQgKCoqKm5yZjJ1YmlvbWVfZGFkYTJfc2VwMjAxOV92MS5SbWQqKiopIHdhcyBkZXZlbG9wZWQgdXNpbmcgW0RBREEyIFBpcGVsaW5lIFR1dG9yaWFsICgxLjEyKV0oaHR0cHM6Ly9iZW5qam5lYi5naXRodWIuaW8vZGFkYTIvdHV0b3JpYWwuaHRtbCkgd2l0aCB0aXBzIGFuZCB0cmlja3MgZnJvbSB0aGUgW1VuaXZlcnNpdHkgb2YgTWFyeWxhbmQgU2hvb2wgb2YgTWVkaWNpbmUgSW5zdGl0dXRlIGZvciBHZW5vbWUgU2NpZW5jZXMgKElHUyldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvKSBbTWljcm9iaW9tZSBBbmFseXNpcyBXb3Jrc2hvcCAoQXByaWwgOC0xMSwgMjAxOSldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvZWR1Y2F0aW9uL3drc2hwX21ldGFnZW5vbWUucGhwKS4gVGhlIG91dHB1dCBvZiB0aGUgREFEQTIgc2NyaXB0ICgqKipkYXRhX21heTIwMTkvcHNfc2VwMjAxOS5SRGF0YSoqKikgaXMgZXhwbG9yZWQgaW4gdGhpcyBkb2N1bWVudC4NCg0KIyBNZXRhIGRhdGE6IHNhbXBsZSBkZXNjcmlwdGlvbg0KYGBge3IgZGF0YX0NCiMgTG9hZCBkYXRhLS0tLQ0KIyBDb3VudHMNCmxvYWQoImRhdGFfc2VwMjAxOS9wc19zZXAyMDE5LlJEYXRhIikNCg0KIyBUYXhvbm9teQ0KbG9hZCgiZGF0YV9zZXAyMDE5L3RheGEuUkRhdGEiKQ0KdGF4YSA8LSBkYXRhLnRhYmxlKHNlcTE2cyA9IHJvd25hbWVzKHRheGEpLA0KICAgICAgICAgICAgICAgICAgIHRheGEpDQpgYGANCg0KKipOT1RFOiBjb3JyZWN0aW9uIHRvIHRoZSBtZXRhLWRhdGEhKiogKDExLzE1LzIwMTkpDQpgYGB7ciBjb3JyZWN0X21ldGFfZGF0YX0NCmNvcnJlY3Rfc2FtcGxlcyA8LSBmcmVhZCgiZGF0YV9zZXAyMDE5LzE2cyBtZXRhZGF0YSBTZXAtMjAxOS5jc3YiKQ0KcHNfc2VwMjAxOUBzYW1fZGF0YSREU1MgPC0gY29ycmVjdF9zYW1wbGVzJERTUw0KYGBgDQoNCiMgU2FtcGxlcw0KYGBge3Igc2FtcGxlc30NCnBzX3NlcDIwMTlAc2FtX2RhdGEkR2Vub3R5cGVfV2VlayA8LSBwYXN0ZShwc19zZXAyMDE5QHNhbV9kYXRhJGdlbm90eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzX3NlcDIwMTlAc2FtX2RhdGEkdGltZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpDQpwc19zZXAyMDE5QHNhbV9kYXRhJElEIDwtIGZhY3RvcihwYXN0ZTAocHNfc2VwMjAxOUBzYW1fZGF0YSRtaWNlX251bSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJGNhZ2UpKQ0KDQpwc19zZXAyMDE5QHNhbV9kYXRhJFRSRUFUTUVOVCA8LSBwYXN0ZTAocHNfc2VwMjAxOUBzYW1fZGF0YSREU1MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNfc2VwMjAxOUBzYW1fZGF0YSRQRUlUQywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJGNyYW5iZXJyeSkNCnBzX3NlcDIwMTlAc2FtX2RhdGEkVFJFQVRNRU5UIDwtIGZhY3Rvcihwc19zZXAyMDE5QHNhbV9kYXRhJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCIwMDAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTEwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMDEiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJOYWl2ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1MrUEVJVEMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkNCg0Kc2FtcGxlcyA8LSBwc19zZXAyMDE5QHNhbV9kYXRhDQpkYXRhdGFibGUoc2FtcGxlcywNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gbnJvdyhzYW1wbGVzKSkpDQpgYGANCg0KIyBQcnVuZSBkYXRhDQpUaGUgT1RVcyB3ZXJlIG1hcHBlZCB0byBCYWN0ZXJpYSAoOTYuMDclKSwgRXVrYXJ5b3RhICgyLjk1JSkgYW5kIEFyY2hlYSAoMC4wMyUpIGtpbmdkb21zLCBhbmQgIDc1IE9UVXMgKDAuOTUlKSB1bmRlZmluZWQuIA0KDQpgYGB7ciBjaGVja19tYXBwaW5nX2tpbmdkb20sIHdhcm5pbmcgPSBGQUxTRSwgZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQp0MSA8LSBkYXRhLnRhYmxlKHRhYmxlKHRheF90YWJsZShwc19zZXAyMDE5KVssICJLaW5nZG9tIl0sDQogICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGUgPSBOVUxMKSkNCnQxJFYxW2lzLm5hKHQxJFYxKV0gPC0gIlVua25vd24iDQoNCnQxWywgcGN0IDo9IE4vc3VtKE4pXQ0Kc2V0b3JkZXIodDEsIC1OKQ0KDQpjb2xuYW1lcyh0MSkgPC0gYygiS2luZ2RvbSIsDQogICAgICAgICAgICAgICAgICAiTnVtYmVyIG9mIE9UVXMiLA0KICAgICAgICAgICAgICAgICAgIlBlcmNlbnQgb2YgT1RVcyIpDQpkYXRhdGFibGUodDEsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIk51bWJlciBvZiBPVFVzIGJ5IEtpbmdkb20iLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3codDEpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSAyLA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKSAlPiUNCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMywNCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNClRoZSB0b3RhbCBvZiA3LDg2NyB1bmlxdWUgc2VxdWVuY2VzIHdlcmUgZm91bmQuIE91dCBvZiB0aG9zZSwgNyw1NTggd2VyZSBtYXBwZWQgdG8gYmFjdGVyaWFsIGdlbm9tZXMuIA0KDQpgYGB7ciBrZWVwX2JhY3RlcmlhfQ0KZGltKHBzX3NlcDIwMTlAb3R1X3RhYmxlQC5EYXRhKQ0KDQojIFJlbW92ZSBPVFUgbm90IG1hcHBlZCB0byBCYWN0ZXJpYQ0KcHMwIDwtIHN1YnNldF90YXhhKHBzX3NlcDIwMTksIA0KICAgICAgICAgICAgICAgICAgIEtpbmdkb20gPT0gIkJhY3RlcmlhIikNCmRpbShwczBAb3R1X3RhYmxlQC5EYXRhKQ0KYGBgDQogIA0KT3V0IG9mIHRoZSA3LDU1OCBPVFVzIDcsMjQ3IGJlbG9uZ2VkIHRvIDEyIFBoeWxhLiAzMTEgb2YgdGhlIE9UVXMgKG9yIDQuMTElIG9mIGJhY3RlcmlhbCBPVFVzKSBjb3VsZCBub3QgYmUgbWFwcGVkIHRvIGEgcGh5bHVtLg0KDQpgYGB7ciBwaHlsdW1fbWFwcGluZ30NCnQyIDwtIGRhdGEudGFibGUodGFibGUodGF4X3RhYmxlKHBzMClbLCAiUGh5bHVtIl0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZSA9IE5VTEwpKQ0KdDIkVjFbaXMubmEodDIkVjEpXSA8LSAiVW5rbm93biINCnNldG9yZGVyKHQyLCAtTikNCnQyWywgcGN0IDo9IE4vc3VtKE4pXQ0Kc2V0b3JkZXIodDIsIC1OKQ0KDQpjb2xuYW1lcyh0MikgPC0gYygiUGh5bHVtIiwNCiAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgT1RVcyIsDQogICAgICAgICAgICAgICAgICAiUGVyY2VudCBvZiBPVFVzIikNCg0KZGF0YXRhYmxlKHQyLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgY2FwdGlvbiA9ICJOdW1iZXIgb2YgQmFjdGVyaWFsIE9UVXMgYnkgUGh5bHVtIiwNCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQyKSkpICU+JQ0KICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gMiwNCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwNCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwNCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkgJT4lDQogIGZvcm1hdFBlcmNlbnRhZ2UoY29sdW1ucyA9IDMsDQogICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikNCmBgYA0KDQojIE9UVSB0YWJsZSAoZmlyc3QgMTAgcm93cykNCmBgYHtyIG90dV90YWJsZSwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQpvdHUgPC0gZGF0YS50YWJsZShwczBAdGF4X3RhYmxlQC5EYXRhLA0KICAgICAgICAgICAgICAgICAgdChwczBAb3R1X3RhYmxlQC5EYXRhKSkNCmRhdGF0YWJsZShoZWFkKG90dSwgMTApLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwNCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSAxMCkpICU+JQ0KICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNzozNiwNCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwNCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwNCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkNCmBgYA0KDQojIFRvdGFsIGNvdW50cyBwZXIgc2FtcGxlIChpLmUuIHNlcXVlbmNpbmcgZGVwdGgpDQpgYGB7ciBzZXFfZGVwdGgsIGZpZy53aWR0aCA9IDEwLGZpZy5oZWlnaHQgPSA1fQ0KdDEgPC0gY29sU3VtcyhvdHVbLCA3Om5jb2wob3R1KV0pDQp0MSA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gbmFtZXModDEpLA0KICAgICAgICAgICAgICAgICBUb3RhbCA9IHQxKQ0KDQp0MiA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gcm93bmFtZXMoc2FtcGxlcyksDQogICAgICAgICAgICAgICAgIElEID0gc2FtcGxlcyRJRCwNCiAgICAgICAgICAgICAgICAgQ0FHRSA9IHNhbXBsZXMkY2FnZSwNCiAgICAgICAgICAgICAgICAgVFJFQVRNRU5UID0gc2FtcGxlcyRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc2FtcGxlcyRnZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgV0VFSyA9IHNhbXBsZXMkdGltZSkNCg0Kc21wbCA8LSBtZXJnZSh0MSwNCiAgICAgICAgICAgICAgdDIsDQogICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KcDEgPC0gZ2dwbG90KHNtcGwsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFRvdGFsLA0KICAgICAgICAgICAgICAgICBmaWxsID0gVFJFQVRNRU5ULA0KICAgICAgICAgICAgICAgICBjb2xvdXIgPSBXRUVLKSkgKw0KICBmYWNldF93cmFwKH4gR2Vub3R5cGUsDQogICAgICAgICAgICAgc2NhbGUgPSAiZnJlZV94IikgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cygiTnVtYmVyIG9mIFJlYWRzIikgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKCJUcmVhdG1lbnQiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpIA0KZ2dwbG90bHkocDEpDQpgYGANCg0KIyBSaWNobmVzcyAoQWxwaGEgZGl2ZXJzaXR5KQ0KU2hhbm5vbiBpbmRleCAoYWthIFNoYW5ub24gZW50aHJvcGh5KSBpcyBjYWxjdWxhdGVkIGFzOiAgDQpIJyA9IC1zdW0oMSB0byBSKXAoaSlsbihwKGkpKSANCldoZW4gdGhlcmUgaXMgZXhhY3RseSAxIHR5cGUgb2YgZGF0YSAoZS5nLiBhIHNpbmdsZSBzcGVjaWVzIGluIHRoZSBzYW1wbGUpLCBIJz0wLiBUaGUgb3Bwb3NpdGUgc2NlbmFyaW8gaXMgd2hlbiB0aGVyZSBhcmUgUj4xIHNwZWNpZXMgcHJlc2VudCBpbiB0aGUgc2FtcGxlIGluIHRoZSBleGFjdCBzYW1lIGFtb3VudHMgYW5kIEgnPWxuKFIpLiAgDQogIA0KU2hhbm5vbidzIGRpdmVyc2l0eSBpbmRleCB3YXMgY2FsY3VsYXRlZCBmb3IgZWFjaCBzYW1wbGUgYW5kIHBsb3RlZCBvdmVyIHRpbWUgdXNpbmcgdGhlIDcsNzY0IGZyb20gdGhlIDEzIFBoeWx1bSBhYm92ZS4NCiAgDQpgYGB7ciBzaGFubm9uX3ZzX2RlcHRoLCBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gNn0NCnNoYW5ub24ubmR4IDwtIGVzdGltYXRlX3JpY2huZXNzKHBzMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmVzID0gIlNoYW5ub24iKQ0KDQpzaGFubm9uLm5keCA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gcm93bmFtZXMoc2hhbm5vbi5uZHgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFubm9uLm5keCkNCg0Kc21wbCA8LSBtZXJnZShzbXBsLA0KICAgICAgICAgICAgICBzaGFubm9uLm5keCwNCiAgICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQ0KDQpwMSA8LSBnZ3Bsb3Qoc21wbCwNCiAgICAgICAgICAgICBhZXMoeCA9IFRvdGFsLA0KICAgICAgICAgICAgICAgICB5ID0gU2hhbm5vbiwNCiAgICAgICAgICAgICAgICAgZmlsbCA9IEdlbm90eXBlLA0KICAgICAgICAgICAgICAgICBzaGFwZSA9IFdFRUspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsNCiAgc2NhbGVfc2hhcGVfbWFudWFsKGJyZWFrcyA9IHVuaXF1ZShzbXBsJFdFRUspLA0KICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gMjE6MjMpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3NoYW5ub25fdnNfZGVwdGgudGlmZiIsDQogICAgIGhlaWdodCA9IDUsDQogICAgIHdpZHRoID0gNiwNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAxKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KZ2dwbG90bHkocDEpDQpgYGANCg0KRXZlbiB0aG91Z2ggKioqZXN0aW1hdGVfcmljaG5lc3MqKiogZnVuY3Rpb24gZG9lcyBub3QgYWRqdXN0IGZvciB0aGUgc2VxdWVuY2luZyBkZXB0aCwgdGhlcmUgaXMgbm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kZXggYW5kIHRoZSBzYW1wbGUncyBzZXF1ZWNpbmcgZGVwdGguIFByb2NlZWQgd2l0aCB0aGUgY29tcGFyaXNvbi4NCg0KIyBTaGFubm9uIGlkZXggb3ZlciB0aW1lDQpgYGB7ciByaWNobmVzcywgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodCA9IDV9DQpwMSA8LSBwbG90X3JpY2huZXNzKHBzMCwNCiAgICAgICAgICAgICAgICAgICAgeCA9ICJ0aW1lIiwgDQogICAgICAgICAgICAgICAgICAgIG1lYXN1cmVzID0gIlNoYW5ub24iKSArDQogIGZhY2V0X3dyYXAofiBnZW5vdHlwZSkgKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gSUQpLA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBUUkVBVE1FTlQpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsDQogICAgICAgICAgICAgc2l6ZSA9IDMsDQogICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdCA9IDEpKQ0KDQpnZ3Bsb3RseShwID0gcDEsDQogICAgICAgICB0b29sdGlwID0gYygiSUQiLA0KICAgICAgICAgICAgICAgICAgICAgInZhbHVlIikpDQoNCnAxIDwtIHAxICsgDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoIiIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3NoYW5ub24udGlmZiIsDQogICAgIGhlaWdodCA9IDQsDQogICAgIHdpZHRoID0gNSwNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAxKQ0KZ3JhcGhpY3Mub2ZmKCkNCmBgYA0KDQpUaGUgcGxvdCBhYm92ZSBzdWdnZXN0cyB0aGF0IHRoZSBsYXJnZXN0IGRpZmZlcmVuY2VzIGluIGFscGhhIGRpdmVyc2l0eSAoYXMgbWVhc3VyZWQgYnkgU2hhbm5vbidzIGluZGV4KSBhcmUgaW4gZ2Vub3R5cGUuDQogIA0KVGVzdCBpZiB0aGUgcmljaG5lc3MgY2hhbmdlZCBiZXR3ZWVuIHRoZSBiYXNlbGluZSBhbmQgV2VlayA4LiAgDQogIA0KYGBge3IgbG1fcmljaG5lc3N9DQpzbXBsJFRSRUFUTUVOVCA8LSBmYWN0b3Ioc21wbCRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiRFNTIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOYWl2ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1MrQ3JhbmJlcnJ5IikpDQoNCnRtcCA8LSBkcm9wbGV2ZWxzKHNtcGxbV0VFSyAhPSAid2VlazEiXSkNCg0KbTEgPC0gbG0oU2hhbm5vbiAgfiBXRUVLKihUUkVBVE1FTlQgKyBHZW5vdHlwZSksDQogICAgICAgICAjIG9mZnNldCA9IFRvdGFsLA0KICAgICAgICAgZGF0YSA9IHRtcCkNCnN1bW1hcnkobTEpDQpgYGANCiAgDQpgYGB7ciBsbWVyX3JpY2huZXNzfQ0KbTIgPC0gbG1lcihTaGFubm9uICB+IFdFRUsqKFRSRUFUTUVOVCArIEdlbm90eXBlKSArICgxIHwgSUQpLA0KICAgICAgICAgICAjIG9mZnNldCA9IFRvdGFsLA0KICAgICAgICAgICBkYXRhID0gdG1wKQ0Kc3VtbWFyeShtMikNCmBgYA0KDQojIENhbGN1bGF0ZSBjaGFuZ2UgaW4gU2hhbm5vbiBpbmRleCBmcm9tIGJhc2VsaW5lDQpgYGB7ciBkZWx0YV9zaGFubm9uLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNX0NCmRkIDwtIHNtcGwNCmRkWywgZGVsdGEgOj0gU2hhbm5vbiAtIFNoYW5ub25bV0VFSyA9PSAiYmFzZWxpbmUiXSwNCiAgIGJ5ID0gSURdDQpkZCRkaWZmIDwtIHBhc3RlKGRkJFdFRUssDQogICAgICAgICAgICAgICAgICItYmFzZWxpbmUiLA0KICAgICAgICAgICAgICAgICBzZXAgPSAiIikNCg0KZGQgPC0gZGRbV0VFSyAhPSAiYmFzZWxpbmUiLF0NCg0KcDEgPC0gZ2dwbG90KGRkLA0KICAgICAgICAgICAgIGFlcyh4ID0gVFJFQVRNRU5ULA0KICAgICAgICAgICAgICAgICB5ID0gZGVsdGEsDQogICAgICAgICAgICAgICAgIGZpbGwgPSBHZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IGRpZmYpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsDQogICAgICAgICAgICAgc2l6ZSA9IDMpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJTaGFubm9uIEluZGV4IFBlcmNlbnQgQ2hhbmdlIGZyb20gQmFzZWxpbmUiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQpwcmludChwMSkNCg0KZGQkVFJFQVRNRU5UIDwtIGZhY3RvcihkZCRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJEU1MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmFpdmUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkNCmRkJEdlbm90eXBlIDwtIGZhY3RvcihkZCRHZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygid2lkZXR5cGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJucmYyS08iKSkNCg0KbTEgPC0gbG0oZGVsdGEgfiBUUkVBVE1FTlQqR2Vub3R5cGUsDQogICAgICAgICBkYXRhID0gZGQpDQpzdW1tYXJ5KG0xKQ0KDQojIE5vIHNpZ25pZmljYW50IGludGVyYWN0aW9ucywgcHJvY2VlZCB3aXRoIDItd2F5IGFuYWx5c2lzDQptMiA8LSBsbShkZWx0YSB+IFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgZGF0YSA9IGRkKQ0Kc3VtbWFyeShtMikNCmBgYA0KDQpBdCBXZWVrIDggdGhlcmUgd2FzIHNpZ25pZmljYW50bHkgc21hbGxlciBpbmNyZWFzZSBvZiBhbHBoYSBkaXZlcnNpdHkgZnJvbSBiYXNlbGluZSBpbiBOcmYyIEtPIGNvbXBhcmVkIHRvIFdULCBhbmQgaW4gRFNTK0NyYW5iZXJyeSBjb21wYXJlZCB0byBEU1Mgb25seS4NCg0KIyBMb2FkIGFtaW5vYWNpZHMNCmBgYHtyIGFtaW5vYWNpZHNfZGF0YX0NCmFhIDwtIGZyZWFkKCJkYXRhX3NlcDIwMTkvc2VwMjAxOV9hbWlub2FjaWRzLmNzdiIpDQoNCmFhIDwtIGFhWyFpcy5uYShJRCksIF0NCmFhJElEIDwtIHBhc3RlMChhYSRJRCwNCiAgICAgICAgICAgICAgICBhYSRDQUdFKQ0KDQpzbXBsMSA8LSB1bmlxdWUoc21wbFssIGMoIklEIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVFJFQVRNRU5UIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2Vub3R5cGUiKV0pDQpzbXBsMSRJRCA8LSBhcy5jaGFyYWN0ZXIoc21wbDEkSUQpDQphYSA8LSBtZXJnZShzbXBsMSwNCiAgICAgICAgICAgIGFhLA0KICAgICAgICAgICAgYnkgPSAiSUQiKQ0KYWFbLCB0cnRfd2VlayA6PSBwYXN0ZShUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgIFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIildDQphYSR0cnRfd2VlayA8LSBmYWN0b3IoYWEkdHJ0X3dlZWssDQogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTmFpdmVfd2VlazIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5haXZlX3dlZWs2IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1Nfd2VlazIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTU193ZWVrNiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK0NyYW5iZXJyeV93ZWVrMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK0NyYW5iZXJyeV93ZWVrNiIgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytQRUlUQ193ZWVrMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDX3dlZWs2IikpDQpgYGANCg0KYGBge3IgYW1pbm9hY2lkc19wbG90cywgZmlnLmhlaWdodCA9IDQsIGZpZy53aWR0aCA9IDV9DQpmb3IgKGkgaW4gODoobmNvbChhYSkgLSAxKSkgew0KICB0bXAgPC0gYWFbLCBjKDEsIDMsIDcsIG5jb2woYWEpLCBpKSwgd2l0aCA9IEZBTFNFXQ0KICBjb2xuYW1lcyh0bXApWzVdIDwtICJZIg0KICBwMSA8LSBnZ3Bsb3QodG1wLA0KICAgICAgICAgICAgICAgYWVzKHggPSB0cnRfd2VlaywNCiAgICAgICAgICAgICAgICAgICB5ID0gWSwNCiAgICAgICAgICAgICAgICAgICBmaWxsID0gR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBJRCkpICsNCiAgICBnZW9tX2xpbmUocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArDQogICAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLA0KICAgICAgICAgICAgICAgc2l6ZSA9IDMsDQogICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGNvbG5hbWVzKGFhKVtpXSkgKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkNCiAgIyB0aWZmKGZpbGVuYW1lID0gcGFzdGUwKCJ0bXAvIiwNCiAgIyAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5hbWVzKGFhKVtpXSwNCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICIudGlmZiIpLA0KICAjICAgICAgaGVpZ2h0ID0gNCwNCiAgIyAgICAgIHdpZHRoID0gNSwNCiAgIyAgICAgIHVuaXRzID0gImluIiwNCiAgIyAgICAgIHJlcyA9IDYwMCwNCiAgIyAgICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCiAgIyBwcmludChwMSkNCiAgIyBncmFwaGljcy5vZmYoKQ0KICANCiAgcHJpbnQocDEpDQp9DQpgYGANCg0KIyBBbWlub2FjaWQgZGF0YSBQQ0ENCmBgYHtyIGFtaW5vYWNpZHNfcGNhfQ0KZHRfcGNhIDwtIGFhWywgQWxhbmluZTpnbHV0YW1pbmVdDQoNCm0xIDwtIHByY29tcChkdF9wY2EpDQpzdW1tYXJ5KG0xKQ0KDQoNCiMgU2VsZWN0IFBDLXMgdG8gcGxpb3QgKFBDMSAmIFBDMikNCmNob2ljZXMgPC0gMToyDQojIFNjb3JlcywgaS5lLiBwb2ludHMgKGRmLnUpDQpkdC5zY3IgPC0gZGF0YS50YWJsZShtMSR4WywgY2hvaWNlc10pDQojIEFkZCBncm91cGluZyB2YXJpYWJsZQ0KZHQuc2NyJGdycCA8LSBhYSR0cnRfd2Vlaw0KZHQuc2NyJFRSRUFUTUVOVCA8LSBhYSRUUkVBVE1FTlQNCmR0LnNjciRXRUVLIDwtIGFhJFdFRUsNCmR0LnNjcg0KDQojIExvYWRpbmdzLCBpLmUuIGFycm93cyAoZGYudikNCmR0LnJvdCA8LSBhcy5kYXRhLmZyYW1lKG0xJHJvdGF0aW9uWywgY2hvaWNlc10pDQpkdC5yb3QkZmVhdCA8LSByb3duYW1lcyhkdC5yb3QpDQpkdC5yb3QgPC0gZGF0YS50YWJsZShkdC5yb3QpDQpkdC5yb3QNCg0KZHQubG9hZCA8LSBtZWx0LmRhdGEudGFibGUoZHQucm90LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9ICJmZWF0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IDE6MiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAicGMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJsb2FkaW5nIikNCmR0LmxvYWQkZmVhdCA8LSBmYWN0b3IoZHQubG9hZCRmZWF0LA0KICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUoZHQubG9hZCRmZWF0KSkNCiMgUGxvdCBsb2FkaW5ncw0KcDAgPC0gZ2dwbG90KGRhdGEgPSBkdC5sb2FkLA0KICAgICAgICAgICAgIGFlcyh4ID0gZmVhdCwNCiAgICAgICAgICAgICAgICAgeSA9IGxvYWRpbmcpKSArDQogIGZhY2V0X3dyYXAofiBwYywNCiAgICAgICAgICAgICBucm93ID0gMikgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBnZ3RpdGxlKCJQQyBMb2FkaW5ncyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQp0aWZmKGZpbGVuYW1lID0gInRtcC9wYy4xLjJfbG9hZGluZ3MudGlmZiIsDQogICAgIGhlaWdodCA9IDUsDQogICAgIHdpZHRoID0gOCwNCiAgICAgdW5pdHMgPSAnaW4nLA0KICAgICByZXMgPSAzMDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAwKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KcHJpbnQocDApDQpgYGANCg0KYGBge3IgYW1pbm9hY2lkc19wY2FfYXhlc30NCiMgQXhpcyBsYWJlbHMNCnUuYXhpcy5sYWJzIDwtIHBhc3RlKGNvbG5hbWVzKGR0LnJvdClbMToyXSwgDQogICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwKm0xJHNkZXZbY2hvaWNlc11eMi9zdW0obTEkc2Rldl4yKSkpDQp1LmF4aXMubGFicw0KYGBgDQoNCmBgYHtyIGFtaW5vYWNpZHNfYmlwbG90LCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwfQ0KIyBCYXNlZCBvbiBGaWd1cmUgcDAsIGtlZXAgb25seSBhIGZldyB2YXJpYWJsZXMgd2l0aCBoaWdoIGxvYWRpbmdzIGluIFBDMSBhbmQgUEMyLS0tLQ0KIyB2YXIua2VlcC5uZHggPC0gd2hpY2goZHQucm90JGZlYXQgJWluJSBjKC4uLikpDQojIE9yIHNlbGVjdCBhbGwNCiMgdmFyLmtlZXAubmR4IDwtIDM6bmNvbChkdDEpDQojIFVzZSBkdC5yb3RbdmFyLmtlZXAubmR4LF0gYW5kIGR0LnJvdCRmZWF0W3Zhci5rZWVwLm5keF0NCnAxIDwtIGdncGxvdChkYXRhID0gZHQucm90LA0KICAgICAgICAgICAgIGFlcyh4ID0gUEMxLA0KICAgICAgICAgICAgICAgICB5ID0gUEMyKSkgKw0KICBjb29yZF9lcXVhbCgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gZHQuc2NyLA0KICAgICAgICAgICAgIGFlcyhmaWxsID0gZ3JwKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fc2VnbWVudChhZXMoeCA9IDAsDQogICAgICAgICAgICAgICAgICAgeSA9IDAsDQogICAgICAgICAgICAgICAgICAgeGVuZCA9IDEwKlBDMSwNCiAgICAgICAgICAgICAgICAgICB5ZW5kID0gMTAqUEMyKSwNCiAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgxLzIsICdwaWNhcycpKSwNCiAgICAgICAgICAgICAgIHNpemUgPSAxLjIsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDExKlBDMSwNCiAgICAgICAgICAgICAgICB5ID0gMTEqUEMyLA0KICAgICAgICAgICAgICAgIGxhYmVsID0gZHQucm90JGZlYXQpLA0KICAgICAgICAgICAgIyBzaXplID0gNSwNCiAgICAgICAgICAgIGhqdXN0ID0gMC41KSArDQogIHNjYWxlX3hfY29udGludW91cyh1LmF4aXMubGFic1sxXSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModS5heGlzLmxhYnNbMl0pICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIkdyb3VwIikgKw0KICBnZ3RpdGxlKCJCaXBsb3Qgb2YgQW1pbm9hY2lkcyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMjApKQ0KdGlmZihmaWxlbmFtZSA9ICJ0bXAvYW1pbm9hY2lkc19iaXBsb3QudGlmZiIsDQogICAgIGhlaWdodCA9IDEwLA0KICAgICB3aWR0aCA9IDEwLA0KICAgICB1bml0cyA9ICdpbicsDQogICAgIHJlcyA9IDMwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQpgYGB7ciBhbWlub2FjaWRzX2JpcGxvdF9ieV93ZWVrLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwfQ0KcDIgPC0gZ2dwbG90KGRhdGEgPSBkdC5yb3QsDQogICAgICAgICAgICAgYWVzKHggPSBQQzEsDQogICAgICAgICAgICAgICAgIHkgPSBQQzIpKSArDQogIGNvb3JkX2VxdWFsKCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBkdC5zY3IsDQogICAgICAgICAgICAgYWVzKGZpbGwgPSBXRUVLKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fc2VnbWVudChhZXMoeCA9IDAsDQogICAgICAgICAgICAgICAgICAgeSA9IDAsDQogICAgICAgICAgICAgICAgICAgeGVuZCA9IDEwKlBDMSwNCiAgICAgICAgICAgICAgICAgICB5ZW5kID0gMTAqUEMyKSwNCiAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgxLzIsICdwaWNhcycpKSwNCiAgICAgICAgICAgICAgIHNpemUgPSAxLjIsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDExKlBDMSwNCiAgICAgICAgICAgICAgICB5ID0gMTEqUEMyLA0KICAgICAgICAgICAgICAgIGxhYmVsID0gZHQucm90JGZlYXQpLA0KICAgICAgICAgICAgIyBzaXplID0gNSwNCiAgICAgICAgICAgIGhqdXN0ID0gMC41KSArDQogIHNjYWxlX3hfY29udGludW91cyh1LmF4aXMubGFic1sxXSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModS5heGlzLmxhYnNbMl0pICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIldlZWsiKSArDQogIGdndGl0bGUoIkJpcGxvdCBvZiBBbWlub2FjaWRzIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAyMCkpDQp0aWZmKGZpbGVuYW1lID0gInRtcC9hbWlub2FjaWRzX2J5X3dlZWtfYmlwbG90LnRpZmYiLA0KICAgICBoZWlnaHQgPSAxMCwNCiAgICAgd2lkdGggPSAxMCwNCiAgICAgdW5pdHMgPSAnaW4nLA0KICAgICByZXMgPSAzMDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAyKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KZ2dwbG90bHkocDIpDQpgYGANCg0KYGBge3IgYW1pbm9hY2lkc19iaXBsb3RfYnlfdHJ0LCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwfQ0KcDIgPC0gZ2dwbG90KGRhdGEgPSBkdC5yb3QsDQogICAgICAgICAgICAgYWVzKHggPSBQQzEsDQogICAgICAgICAgICAgICAgIHkgPSBQQzIpKSArDQogIGNvb3JkX2VxdWFsKCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBkdC5zY3IsDQogICAgICAgICAgICAgYWVzKGZpbGwgPSBUUkVBVE1FTlQpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsDQogICAgICAgICAgICAgc2l6ZSA9IDIsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwNCiAgICAgICAgICAgICAgICAgICB5ID0gMCwNCiAgICAgICAgICAgICAgICAgICB4ZW5kID0gMTAqUEMxLA0KICAgICAgICAgICAgICAgICAgIHllbmQgPSAxMCpQQzIpLA0KICAgICAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDEvMiwgJ3BpY2FzJykpLA0KICAgICAgICAgICAgICAgc2l6ZSA9IDEuMiwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMTEqUEMxLA0KICAgICAgICAgICAgICAgIHkgPSAxMSpQQzIsDQogICAgICAgICAgICAgICAgbGFiZWwgPSBkdC5yb3QkZmVhdCksDQogICAgICAgICAgICAjIHNpemUgPSA1LA0KICAgICAgICAgICAgaGp1c3QgPSAwLjUpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHUuYXhpcy5sYWJzWzFdKSArDQogIHNjYWxlX3lfY29udGludW91cyh1LmF4aXMubGFic1syXSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiVHJlYXRtZW50IikgKw0KICBnZ3RpdGxlKCJCaXBsb3Qgb2YgQW1pbm9hY2lkcyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMjApKQ0KdGlmZihmaWxlbmFtZSA9ICJ0bXAvYW1pbm9hY2lkc19ieV90cnRfYmlwbG90LnRpZmYiLA0KICAgICBoZWlnaHQgPSAxMCwNCiAgICAgd2lkdGggPSAxMCwNCiAgICAgdW5pdHMgPSAnaW4nLA0KICAgICByZXMgPSAzMDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAyKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KZ2dwbG90bHkocDIpDQpgYGANCiMgUmVtb3ZlIHVubWFwcGVkIE9UVXMNClRoZSAzMTEgdW5tYXBwZWQgT1RVcyB3ZXJlIHJlbW92ZWQgZnJvbSBmdXJ0aGVyIGFuYWx5c2lzICh3aXRoIDcsMjQ3IE9UVXMgbGVmdCkuDQpgYGB7ciByZW1vdmVfdW5tYXBwZWRfb3R1X3BoeWx1bX0NCnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIA0KICAgICAgICAgICAgICAgICAgICFpcy5uYShQaHlsdW0pKQ0KZGltKHBzMUBvdHVfdGFibGVALkRhdGEpDQpgYGANCg0KIyBDb3VudHMgYXQgUGh5bHVtIGxldmVsDQpgYGB7ciBjb3VudHNfcCwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQpjb3VudHNfcCA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiUGh5bHVtIikNCnNldG9yZGVyKGNvdW50c19wLCAtYDE5MDkxOS0wMWApDQpkYXRhdGFibGUoY291bnRzX3AsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3coY291bnRzX3ApKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSAyOm5jb2woY291bnRzX3ApLA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKQ0KYGBgDQoNCiMgUmVsYXRpdmUgYWJ1bmRhbmNlICglKSBhdCBQaHlsdW0gbGV2ZWwNCmBgYHtyIHJhX3AsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQ0KcmFfcCA8LSByYV9ieV90YXhfcmFuayhjb3VudHMgPSBjb3VudHNfcCwNCiAgICAgICAgICAgICAgICAgICAgICAgcGN0ID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0ID0gNCkNCg0KZGF0YXRhYmxlKHJhX3AsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3cocmFfcCkpKSAlPiUNCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMjpuY29sKGNvdW50c19wKSwNCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNClJlbW92ZSBwaHlsYSB3aXRoIHJlbGF0aXZlIGFidW5kYW5jZSBvZiA+PSAxJSBpbiBsZXNzIHRoYW4gMTAlIG9mIHNhbXBsZXMuDQoNCmBgYHtyIHByZXZfcH0NCnQxIDwtIGRhdGEudGFibGUoUGh5bHVtID0gcmFfcCRQaHlsdW0sDQogICAgICAgICAgICAgICAgIGBOdW1iZXIgb2YgU2FtcGxlc2AgPSByb3dTdW1zKHJhX3BbLCAyOm5jb2wocmFfcCldID49IDAuMDEpKQ0KdDEkYFBlcmNlbnQgU2FtcGxlc2AgPC0gIHQxJGBOdW1iZXIgb2YgU2FtcGxlc2AvNzINCg0Kc2V0b3JkZXIodDEsIC1gTnVtYmVyIG9mIFNhbXBsZXNgKQ0KZGF0YXRhYmxlKHQxLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwNCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQxKSkpICU+JQ0KICBmb3JtYXRQZXJjZW50YWdlKGNvbHVtbnMgPSAzLA0KICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDEpDQpgYGANCg0KV2Ugd2lsbCByZW1vdmUgQ2hsYW15ZGlhZSBmcm9tIHRoaXMgYW5hbHlzaXMuDQoNCmBgYHtyIGtlZXBfNl9waHlsYSwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQprZWVwX3AgPC0gdDEkUGh5bHVtW3QxJGBQZXJjZW50IFNhbXBsZXNgID49IDAuMV0NCiMgIyBLZWVwIGFsbA0KIyBrZWVwX3AgPC0gdDEkUGh5bHVtDQoNCnBhc3RlMChrZWVwX3AsIGNvbGxhcHNlID0gIiwgIikNCg0KcHMxIDwtIHN1YnNldF90YXhhKHBzMCwgDQogICAgICAgICAgICAgICAgICAgUGh5bHVtICVpbiUga2VlcF9wICkNCm90dTEgPC0gZGF0YS50YWJsZShwczFAdGF4X3RhYmxlQC5EYXRhLA0KICAgICAgICAgICAgICAgICAgIHQocHMxQG90dV90YWJsZUAuRGF0YSkpDQoNCmRhdGF0YWJsZShoZWFkKG90dTEsIDEwKSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsDQogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApKSAlPiUNCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDc6bmNvbChvdHUxKSwNCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwNCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwNCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkNCmBgYA0KDQpYWCBPVFVzLCBkb3duIGZyb20gWVkgT1RVcyBpbiB0aGUgcHJldmlvdXMgdGFibGUuDQoNCg0KIyBSZWxhdGl2ZSBBYnVuZGFuY2UgaW4gU2FtcGxlcyBhdCBEaWZmZXJlbnQgVGF4b25vbWljIFJhbmtzDQojIyAxLiBDbGFzcw0KYGBge3IgY291bnRzX2MsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX2MgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJDbGFzcyIpDQpyYV9jIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19jKQ0KDQp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2xhc3MiKV0pDQoNCnJhX2MgPC0gbWVyZ2UodGF4LnJhbmtzLA0KICAgICAgICAgICAgICByYV9jLA0KICAgICAgICAgICAgICBieSA9ICJDbGFzcyIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfY1ssIDM6bmNvbChyYV9jKV0pDQoNCnJhX2MkQ2xhc3MgPC0gZmFjdG9yKHJhX2MkQ2xhc3MsDQogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9jJENsYXNzW29yZGVyKHRvdGFsKV0pDQoNCnJhX2MkUGh5bHVtIDwtIGZhY3RvcihyYV9jJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfYyRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9jLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2MpLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gQ2xhc3MsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKw0KICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLA0KICAgICAgICAgICAgIG5yb3cgPSAzKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KZ2dwbG90bHkocDEpDQpgYGANCg0KYGBge3IgbWVhbnNfYywgZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCmxyYSA8LSByYV9tZWx0KHJhID0gcmFfYywNCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzbXBsLA0KICAgICAgICAgICAgICAgc2FtcGxlX25hbWUgPSAiU0FNUExFX05BTUUiKQ0KDQptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGxpc3QoV2VlayA9IGxyYSRXRUVLLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBscmEkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgPSBscmEkQ2xhc3MpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkNCm11WywgdG90YWwgOj0gc3VtKHgpLA0KICAgYnkgPSAiQ2xhc3MiXQ0KdWwgPC0gdW5pcXVlKG11WywgYygiQ2xhc3MiLCANCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQ0KdWwgPC0gdWxbb3JkZXIodG90YWwpLF0NCm11JENsYXNzIDwtIGZhY3RvcihtdSRDbGFzcywNCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJENsYXNzKQ0KbXUkdG90YWwgPC0gTlVMTA0KDQpkYXRhdGFibGUobXUsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA1LA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNCg0KYGBge3IgbWVhbnNfY19wMCwgZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDd9DQptdSRUcnRfR2Vub3R5cGUgPC0gZmFjdG9yKHBhc3RlKG11JFRyZWF0bWVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIikpDQoNCnAwIDwtIGdncGxvdChtdSwNCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssDQogICAgICAgICAgICAgICAgIHkgPSB4LA0KICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IENsYXNzLA0KICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsNCiAgZ2VvbV9saW5lKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gVHJ0X0dlbm90eXBlKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41LA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X2NsYXNzX292ZXJfdGltZS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gNSwNCiAgICAgd2lkdGggPSA3LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDApDQpncmFwaGljcy5vZmYoKQ0KDQpwcmludChwMCkNCmBgYA0KDQoNCmBgYHtyIG1lYW5zX2NfcDEsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA5fQ0KcDEgPC0gZ2dwbG90KG11LA0KICAgICAgICAgICAgIGFlcyh4ID0geCwNCiAgICAgICAgICAgICAgICAgeSA9IENsYXNzLA0KICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgc2hhcGUgPSBXZWVrKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9jbGFzc19yYS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gNCwNCiAgICAgd2lkdGggPSA3LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQojIyAyLiBPcmRlcg0KYGBge3IgY291bnRzX28sIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX28gPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJPcmRlciIpDQpyYV9vIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19vKQ0KDQp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3JkZXIiKV0pDQoNCnJhX28gPC0gbWVyZ2UodGF4LnJhbmtzLA0KICAgICAgICAgICAgICByYV9vLA0KICAgICAgICAgICAgICBieSA9ICJPcmRlciIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfb1ssIDM6bmNvbChyYV9vKV0pDQoNCnJhX28kT3JkZXIgPC0gZmFjdG9yKHJhX28kT3JkZXIsDQogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9vJE9yZGVyW29yZGVyKHRvdGFsKV0pDQoNCnJhX28kUGh5bHVtIDwtIGZhY3RvcihyYV9vJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfbyRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9vLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX28pLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gT3JkZXIsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKw0KICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLA0KICAgICAgICAgICAgIG5yb3cgPSAzKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KZ2dwbG90bHkocDEpDQpgYGANCg0KYGBge3IgbWVhbnNfbywgZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCmxyYSA8LSByYV9tZWx0KHJhID0gcmFfbywNCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzbXBsLA0KICAgICAgICAgICAgICAgc2FtcGxlX25hbWUgPSAiU0FNUExFX05BTUUiKQ0KDQptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGxpc3QoV2VlayA9IGxyYSRXRUVLLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBscmEkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3JkZXIgPSBscmEkT3JkZXIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkNCm11WywgdG90YWwgOj0gc3VtKHgpLA0KICAgYnkgPSAiT3JkZXIiXQ0KdWwgPC0gdW5pcXVlKG11WywgYygiT3JkZXIiLCANCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQ0KdWwgPC0gdWxbb3JkZXIodG90YWwpLF0NCm11JE9yZGVyIDwtIGZhY3RvcihtdSRPcmRlciwNCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJE9yZGVyKQ0KbXUkdG90YWwgPC0gTlVMTA0KDQpkYXRhdGFibGUobXUsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA1LA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNCmBgYHtyIG1lYW5zX29fcDAsIGZpZy53aWR0aCA9IDksIGZpZy5oZWlnaHQgPSA3fQ0KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11JEdlbm90eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpKQ0KDQpwMCA8LSBnZ3Bsb3QobXUsDQogICAgICAgICAgICAgYWVzKHggPSBXZWVrLA0KICAgICAgICAgICAgICAgICB5ID0geCwNCiAgICAgICAgICAgICAgICAgZ3JvdXAgPSBUcnRfR2Vub3R5cGUpKSArDQogIGZhY2V0X3dyYXAofiBPcmRlciwNCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArDQogIGdlb21fbGluZShwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksDQogICAgICAgICAgICAgc2hhcGUgPSAyMSwNCiAgICAgICAgICAgICBzaXplID0gMiwNCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9PcmRlcl9vdmVyX3RpbWUudGlmZiIsDQogICAgIGhlaWdodCA9IDUsDQogICAgIHdpZHRoID0gNywNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAwKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KcHJpbnQocDApDQpgYGANCg0KYGBge3IgbWVhbnNfb19wMSwgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDl9DQpwMSA8LSBnZ3Bsb3QobXUsDQogICAgICAgICAgICAgYWVzKHggPSB4LA0KICAgICAgICAgICAgICAgICB5ID0gT3JkZXIsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJ0X0dlbm90eXBlLA0KICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X09yZGVyX3JhLnRpZmYiLA0KICAgICBoZWlnaHQgPSA0LA0KICAgICB3aWR0aCA9IDcsDQogICAgIHVuaXRzID0gImluIiwNCiAgICAgcmVzID0gNjAwLA0KICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpDQpwcmludChwMSkNCmdyYXBoaWNzLm9mZigpDQoNCmdncGxvdGx5KHAxKQ0KYGBgDQoNCiMjIDMuIEZhbWlseQ0KYGBge3IgY291bnRzX2YsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX2YgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJGYW1pbHkiKQ0KcmFfZiA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfZikNCg0KdGF4LnJhbmtzIDwtIHVuaXF1ZShvdHUxWywgYygiUGh5bHVtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhbWlseSIpXSkNCg0KcmFfZiA8LSBtZXJnZSh0YXgucmFua3MsDQogICAgICAgICAgICAgIHJhX2YsDQogICAgICAgICAgICAgIGJ5ID0gIkZhbWlseSIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfZlssIDM6bmNvbChyYV9mKV0pDQoNCnJhX2YkRmFtaWx5IDwtIGZhY3RvcihyYV9mJEZhbWlseSwNCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX2YkRmFtaWx5W29yZGVyKHRvdGFsKV0pDQoNCnJhX2YkUGh5bHVtIDwtIGZhY3RvcihyYV9mJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfZiRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9mLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2YpLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gRmFtaWx5LA0KICAgICAgICAgICAgICAgICBjb2xvciA9IFBoeWx1bSkpICsNCiAgZmFjZXRfd3JhcCh+IFdFRUsgKyBUUkVBVE1FTlQgKyBHZW5vdHlwZSwNCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwNCiAgICAgICAgICAgICBucm93ID0gMykgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkNCmdncGxvdGx5KHAxKQ0KYGBgDQoNCmBgYHtyIG1lYW5zX2YsIGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX2YsDQogICAgICAgICAgICAgICBzYW1wbGVzID0gc21wbCwNCiAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lID0gIlNBTVBMRV9OQU1FIikNCg0KbXUgPC0gZGF0YS50YWJsZShhZ2dyZWdhdGUobHJhJFJBLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBsaXN0KFdlZWsgPSBscmEkV0VFSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gbHJhJEdlbm90eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhbWlseSA9IGxyYSRGYW1pbHkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkNCm11WywgdG90YWwgOj0gc3VtKHgpLA0KICAgYnkgPSAiRmFtaWx5Il0NCnVsIDwtIHVuaXF1ZShtdVssIGMoIkZhbWlseSIsIA0KICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pDQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQ0KbXUkRmFtaWx5IDwtIGZhY3RvcihtdSRGYW1pbHksDQogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRGYW1pbHkpDQptdSR0b3RhbCA8LSBOVUxMDQoNCmRhdGF0YWJsZShtdSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsDQogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5ID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA1LA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNCk5PVEU6IG9ubHkgdGhlIGZpcnN0IDI0IGZhbWlsaWVzIGhhZCBsYXJnZSBlbm91Z2ggY291bnRzIC0gcGxvdGluZyBvbmx5IHRoZW0uICANCiAgDQpgYGB7ciBtZWFuc19mX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30NCm11JFRydF9HZW5vdHlwZSA8LSBmYWN0b3IocGFzdGUobXUkVHJlYXRtZW50LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdSRHZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkNCm11MSA8LSBkcm9wbGV2ZWxzKG11W0ZhbWlseSAlaW4lIGxldmVscyhtdSRGYW1pbHkpW25sZXZlbHMobXUkRmFtaWx5KToobmxldmVscyhtdSRGYW1pbHkpIC0gMjQpXSwgXSkNCg0KcDAgPC0gZ2dwbG90KG11MSwNCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssDQogICAgICAgICAgICAgICAgIHkgPSB4LA0KICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IEZhbWlseSwNCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArDQogIGdlb21fbGluZShwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksDQogICAgICAgICAgICAgc2hhcGUgPSAyMSwNCiAgICAgICAgICAgICBzaXplID0gMiwNCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9GYW1pbHlfb3Zlcl90aW1lLnRpZmYiLA0KICAgICBoZWlnaHQgPSA3LA0KICAgICB3aWR0aCA9IDksDQogICAgIHVuaXRzID0gImluIiwNCiAgICAgcmVzID0gNjAwLA0KICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpDQpwcmludChwMCkNCmdyYXBoaWNzLm9mZigpDQoNCnByaW50KHAwKQ0KYGBgDQoNCmBgYHtyIG1lYW5zX2ZfcDEsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA5fQ0KcDEgPC0gZ2dwbG90KG11MSwNCiAgICAgICAgICAgICBhZXMoeCA9IHgsDQogICAgICAgICAgICAgICAgIHkgPSBGYW1pbHksDQogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJ0X0dlbm90eXBlLA0KICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X0ZhbWlseV9yYS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gNCwNCiAgICAgd2lkdGggPSA3LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQojIyA0LiBHZW51cw0KYGBge3IgY291bnRzX2csIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX2cgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJHZW51cyIpDQpyYV9nIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19nKQ0KDQp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VudXMiKV0pDQoNCnJhX2cgPC0gbWVyZ2UodGF4LnJhbmtzLA0KICAgICAgICAgICAgICByYV9nLA0KICAgICAgICAgICAgICBieSA9ICJHZW51cyIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfZ1ssIDM6bmNvbChyYV9nKV0pDQoNCnJhX2ckR2VudXMgPC0gZmFjdG9yKHJhX2ckR2VudXMsDQogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9nJEdlbnVzW29yZGVyKHRvdGFsKV0pDQoNCnJhX2ckUGh5bHVtIDwtIGZhY3RvcihyYV9nJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfZyRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9nLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2cpLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gR2VudXMsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKw0KICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLA0KICAgICAgICAgICAgIG5yb3cgPSAzKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KZ2dwbG90bHkocDEpDQpgYGANCg0KDQpgYGB7ciBtZWFuc19nLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KbHJhIDwtIHJhX21lbHQocmEgPSByYV9nLA0KICAgICAgICAgICAgICAgc2FtcGxlcyA9IHNtcGwsDQogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpDQoNCm11IDwtIGRhdGEudGFibGUoYWdncmVnYXRlKGxyYSRSQSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlYXRtZW50ID0gbHJhJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IGxyYSRHZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW51cyA9IGxyYSRHZW51cyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSAibWVhbiIpKQ0KbXVbLCB0b3RhbCA6PSBzdW0oeCksDQogICBieSA9ICJHZW51cyJdDQp1bCA8LSB1bmlxdWUobXVbLCBjKCJHZW51cyIsIA0KICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pDQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQ0KbXUkR2VudXMgPC0gZmFjdG9yKG11JEdlbnVzLA0KICAgICAgICAgICAgICAgICAgIGxldmVsID0gdWwkR2VudXMpDQptdSR0b3RhbCA8LSBOVUxMDQoNCmRhdGF0YWJsZShtdSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsDQogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgR2VudXMgPSBsaXN0KGxpc3QoMywgJ2Rlc2MnKSkpKSAlPiUNCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDUsDQogICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gIiIsDQogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsDQogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpDQpgYGANCg0KYGBge3IgbWVhbnNfZ19wMCwgZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDd9DQptdSRUcnRfR2Vub3R5cGUgPC0gZmFjdG9yKHBhc3RlKG11JFRyZWF0bWVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIikpDQptdTEgPC0gZHJvcGxldmVscyhtdVtHZW51cyAlaW4lIGxldmVscyhtdSRHZW51cylbbmxldmVscyhtdSRHZW51cyk6KG5sZXZlbHMobXUkR2VudXMpIC0gMzUpXSwgXSkNCg0KcDAgPC0gZ2dwbG90KG11MSwNCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssDQogICAgICAgICAgICAgICAgIHkgPSB4LA0KICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IEdlbnVzLA0KICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsNCiAgZ2VvbV9saW5lKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gVHJ0X0dlbm90eXBlKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41LA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X0dlbnVzX292ZXJfdGltZS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gOSwNCiAgICAgd2lkdGggPSAxMiwNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAwKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KcHJpbnQocDApDQpgYGANCg0KYGBge3IgbWVhbnNfZ19wMSwgZmlnLmhlaWdodCA9IDksIGZpZy53aWR0aCA9IDl9DQpwMSA8LSBnZ3Bsb3QobXUxLA0KICAgICAgICAgICAgIGFlcyh4ID0geCwNCiAgICAgICAgICAgICAgICAgeSA9IEdlbnVzLA0KICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgc2hhcGUgPSBXZWVrKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9HZW51c19yYS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gOSwNCiAgICAgd2lkdGggPSA5LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQoNCg0KIyBTZXNzaW9uIEluZm9ybWF0aW9uDQpgYGB7ciBpbmZvLGV2YWw9VFJVRX0NCnNlc3Npb25JbmZvKCkNCmBgYA==